package Offer2019;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 1 验证volatile的可见性
 * 1.1 假如 int number = 0； number变量之前根本没有添加volatile关键字修饰,没有可见性
 * 1.2 添加volatile，可以解决可见性问题
 * <p>
 * 2 验证volatile不保证原子性
 * 2.1 原子性指的是什么意思？
 * 不可分割性，完整性，也即某个线程正在做某个具体业务时，中间不可以被加塞或者被分割。需要整体完整，要么同时成功，要么同时失败。
 */
public class VolatileDemo {

    public static void main(String[] args) {
        MyData myData = new MyData();
        for (int i = 1; i <= 20; i++) {
            new Thread(() -> {
                for (int j = 1; j <= 1000; j++) {
                    myData.addPlusPlus();
                    myData.addMyAtomic();
                }
            }, String.valueOf(i)).start();
        }

        //需要等待前面20个线程全部执行完，在用main线程取得最终的结果值是多少
        while (Thread.activeCount() > 2) {
            //main 线程 GC线程
            Thread.yield();
        }
        System.out.println(Thread.currentThread().getName() + "\t int type final number value:" + myData.number);
        System.out.println(Thread.currentThread().getName() + "\t AtomicInteger type final number value:" + myData.atomicInteger);
    }
}


class MyData {
    volatile int number = 0;

    public void addT060() {
        this.number = 60;
    }

    //number加了volatile关键字
    public void addPlusPlus() {
        number++;
    }

    AtomicInteger atomicInteger = new AtomicInteger();

    public void addMyAtomic() {
        atomicInteger.getAndIncrement();
    }

}
